package org.mybatis.demo;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.ExecutorType;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Before;
import org.junit.Test;
import org.mybatis.demo.domain.User;
import org.mybatis.demo.mapper.UserMapper;
import org.mybatis.demo.plugins.PageHelper;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

/**
 * @author ${USER}
 */
public class App {
  private SqlSessionFactory sqlSessionFactory;

  @Before
  public void init() throws IOException
  {
    // 加载 XML 资源文件
    InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
    // 解析 XML 构建 Configuration， 创建 DefaultSqlSessionFactory 对象
    sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
  }

  @Test
  public void selectOne()
  {
    SqlSession session = sqlSessionFactory.openSession();
    UserMapper mapper = session.getMapper(UserMapper.class);
    User user = mapper.selectUser(100);
    System.out.println(user);

    // 下面的方法是等价的
    //    Object o = session.selectOne("org.mybatis.demo.mapper.UserMapper.selectUser");
    //    System.out.println(o);
  }

  @Test
  public void selectList()
  {
    SqlSession session = sqlSessionFactory.openSession();
    UserMapper mapper = session.getMapper(UserMapper.class);
    PageHelper.startPage(1, 15);
    List<User> users = mapper.selectUsers();
    System.out.println(users);
  }

  @Test
  public void batchAddUser1()
  {
    SqlSession session = sqlSessionFactory.openSession();
    UserMapper mapper = session.getMapper(UserMapper.class);
    long start = System.currentTimeMillis();
    for (int i = 0; i < 10000; i++) {
      mapper.addUser(new User(i, "user_" + i));
    }

    System.out.println(System.currentTimeMillis() - start); // 1632
    session.commit();
    session.close();
  }

  @Test
  public void batchAddUser2()
  {
    // 使用 BatchExecutor 批量执行，虽然执行了多次，但是 SQL 只编译了一次，最后在事务提交的时候，一次性把参数提交调用，
    sqlSessionFactory.getConfiguration().setDefaultExecutorType(ExecutorType.BATCH);
    SqlSession session = sqlSessionFactory.openSession();
    session.getConfiguration().setDefaultExecutorType(ExecutorType.BATCH);
    UserMapper mapper = session.getMapper(UserMapper.class);
    long start = System.currentTimeMillis();
    for (int i = 0; i < 10000; i++) {
      mapper.addUser(new User(i, "user_" + i));
    }

    System.out.println(System.currentTimeMillis() - start); // 370
    session.commit();
    session.close();
  }

  @Test
  public void batchAddUser3()
  {
    // 在外面使用 Java 拼接一条很长的 SQL，只执行了一次，但是 SQL 太长的话，编译预处理会比较耗时。
    SqlSession session = sqlSessionFactory.openSession();
    UserMapper mapper = session.getMapper(UserMapper.class);
    long start = System.currentTimeMillis();
    List<User> users = new ArrayList<>();
    for (int i = 0; i < 10000; i++) {
      users.add(new User(i, "user_" + i));
    }

    mapper.batchAddUser(users);
    System.out.println(System.currentTimeMillis() - start); // 414

    session.commit();
    session.close();
  }
}
